package client;

//import java.applet.*; 
import java.awt.*; 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*; 
import java.net.*; 
import java.util.*; 

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import com.oreilly.servlet.HttpMessage; 

public class HttpChatApplet extends JApplet implements Runnable {
	final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;
	JTextField userName;
	JTextArea chatArea;
	JTextField cEntry; 
	Thread thread; 
	String user = null; 
	
	public void init() { 
		// Check if this applet was loaded directly from the filesystem. 
		// If so, explain to the user that this applet needs to be loaded 
		// from a server in order to communicate with that server's servlets. 
		URL codebase = getCodeBase(); 
		if (!"http".equals(codebase.getProtocol()) && 
				!"https".equals(codebase.getProtocol())) { 
			System.out.println(); System.out.println("*** Whoops! ***"); 
			System.out.println("This applet must be loaded from a web server."); 
			System.out.println("Please try again, this time fetching the HTML"); 
			System.out.println("file containing this servlet as"); 
			System.out.println("\"http://server:port/file.html\"."); 
			System.out.println(); System.exit(1); 
			}  
		// Set up the user interface... 
		// On top, a large TextArea showing what everyone's saying. 
		// Underneath, a labeled TextField to accept this user's input.
		
		JLabel userLabel = new JLabel("Nick:");
		JLabel chatLabel = new JLabel("Chat:");
		TextHandler handler = new TextHandler();
		
		userName = new JTextField(10);

		cEntry = new JTextField(20);
		cEntry.addKeyListener(handler);
		
		chatArea = new JTextArea(10,15);
		chatArea.setEditable(false);
		
		JScrollPane cArea = new JScrollPane(chatArea);
		GridBagLayout gridBag = new GridBagLayout();
		Container contentPane = getContentPane();
		if (RIGHT_TO_LEFT) {
            contentPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }		
		contentPane.setLayout(gridBag);
		GridBagConstraints gridCons = new GridBagConstraints();
		if (shouldFill) {
			//natural height, maximum width
			gridCons.fill = GridBagConstraints.HORIZONTAL;
			}
		if (shouldWeightX) {
			gridCons.weightx = 0.1;
			}
		gridCons.fill = GridBagConstraints.HORIZONTAL;
		gridCons.gridx = 0;
		gridCons.gridy = 0;
		contentPane.add(userLabel, gridCons);
		
		gridCons.fill = GridBagConstraints.HORIZONTAL;
		gridCons.weightx = 0.8;
		gridCons.gridx = 1;
		gridCons.gridy = 0;
		contentPane.add(userName, gridCons);
		
		JButton setButton = new JButton("Set");
		gridCons.fill = GridBagConstraints.HORIZONTAL;
		gridCons.weightx = 0.1;
		gridCons.gridx = 2;
		gridCons.gridy = 0;
		contentPane.add(setButton, gridCons);
		setButton.addActionListener(new ButtonHandler());
		
		gridCons.gridx = 0;
		gridCons.gridy = 1;
		gridCons.weightx = 0.1;
		contentPane.add(chatLabel, gridCons);
		
		gridCons.fill = GridBagConstraints.HORIZONTAL;
		gridCons.gridwidth = 2;
		gridCons.weightx = 1.0;
		gridCons.gridx = 1;
		gridCons.gridy = 1;
		contentPane.add(cEntry, gridCons);

		gridCons.fill = GridBagConstraints.HORIZONTAL;
		gridCons.ipady = 60;
		gridCons.gridwidth = 3;
		gridCons.gridx = 0;
		gridCons.gridy = 2;
		gridCons.weightx = 1.0;
		gridCons.weighty = 1.0;
		contentPane.add(cArea, gridCons);
		
		if (user == null) user = "Anonymous";
		} 
	
	public void start() { 
		thread = new Thread(this); 
		thread.start(); 
		} 
	
	public String getNextMessage() { 
		String nextMessage = null; 
		while (nextMessage == null) { 
			try { 
				URL url = new URL(getCodeBase(), "/Chat_Applet/chatservlet");
				System.out.println(url.toString()+"\n");
				HttpMessage msg = new HttpMessage(url); 
				InputStream in = msg.sendGetMessage(); 
				BufferedReader data = new BufferedReader(new InputStreamReader(in)); 
				nextMessage = data.readLine(); 
				System.out.println(nextMessage);
				} catch (SocketException e) { 
					// Can't connect to host, report it and wait before trying again 
				System.out.println("Can't connect to host: " + e.getMessage()); 
				try { 
					Thread.sleep(5000); 
				} catch (InterruptedException ignored) { } 
				} catch (FileNotFoundException e) { 
				// Servlet doesn't exist, report it and wait before trying again 
				System.out.println("Resource not found: " + e.getMessage()); 
				try { 
					Thread.sleep(5000); 
					} catch (InterruptedException ignored) { } 
					} catch (Exception e) { // Some other problem, report it and wait before trying again 
					System.out.println("General exception: " + e.getClass().getName() + ": " + e.getMessage()); 
				try { 
					Thread.sleep(1000); 
				} catch (InterruptedException ignored) { } } 
					} return nextMessage + "\n"; 
				} 
	
	public void run() { 
		while (true) { 
			chatArea.append(getNextMessage()); 
			} 
		} 
	
	void broadcastMessage(String message) { 
		message = user + ": " + message; 
		// Pre-pend the speaker's name 
		try { 
			URL url = new URL(getCodeBase(), "/Chat_Applet/chatservlet"); 
			HttpMessage msg = new HttpMessage(url); 
			Properties props = new Properties(); 
			props.put("message", message); 
			msg.sendPostMessage(props); 
			} catch (SocketException e) { 
				// Can't connect to host, report it and abandon the broadcast 
				System.out.println("Can't connect to host: " + e.getMessage()); 
			} catch (FileNotFoundException e) { 
				// Servlet doesn't exist, report it and abandon the broadcast 
				System.out.println("Resource not found: " + e.getMessage()); 
			} catch (Exception e) { 
				// Some other problem, report it and abandon the broadcast 
				System.out.println("General exception: " + e.getClass().getName() + ": " + e.getMessage());
			} 
		} 
	
	private class TextHandler extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
				String text = cEntry.getText();
				if(e.getKeyCode() == 10 && !text.equals("")) {
					cEntry.setText("");
					broadcastMessage(text);
				}
		}
	}
	
	private class ButtonHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if(userName.getText().length()>0) {
				user = userName.getText();
				chatArea.append("Nickname set as: "+user+"\n");
				userName.setText("");
			}
		}
	}
}